/*
 * CS_REQ_FAIRY_REBIRTH.cpp
 *
 *  Created on: 2013. 7. 23.
 *      Author: mega@gamevil.com
 */

#include "../../Command.h"
#include "../../User.h"
#include "../../Enum.h"
#include "../../NResource/Static.h"
#include "../../NUtil/Utils.h"
#include "../../NLogic/Item.h"
#include "../../NLogic/Bag.h"
#include "../../NLogic/Equip.h"
#include "../../NLogic/Static.h"

namespace ProjectZ { namespace NCommand {

void SendFailFairyRebirth(User * pUser, int res)
{
	::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();
	*pAck << static_cast<int16_t>(res);
	*pAck << static_cast<uint64_t>(0);
	pAck->MakePacket(CMD_SC_REQ_FAIRY_REBIRTH);
	pUser->Send(pAck);
}

void Command::CS_REQ_FAIRY_REBIRTH(User * pUser, ::Network::Packet * pPacket)
{
/*	CS_REQ_FAIRY_REBIRTH	0x1504
	{
		u8	count max 8							// 8개의 페어리로 환생가능
		{
			u64 u64item_seq;					// 부활 아이템 시퀀스
		}
	}
	SC_REQ_FAIRY_REBIRTH	0x1505
	{
		s16	u16ack;
		u64	item_seq;				// 아이템 seq
	}*/

	PREPARE_PACKET;

	char fairyCount = 0;

	*pPacket >> fairyCount;

	// 페어리 환생의 재료 페어리는 8개
	if (8 != fairyCount)
	{
		SendFailFairyRebirth(pUser, ACK_UNKNOWN_ERROR);
		return;
	}

	// 페어리 인벤 확인
	NLogic::Bag * pBag = pUser->GetBag(BAG_TYPE_FAIRY);
	if (pBag == NULL)
	{
		DEBUGLOG("CS_REQ_FAIRY_REBIRTH : pBag is NULL!!");
		SendFailFairyRebirth(pUser, ACK_UNKNOWN_ERROR);
		return;
	}

	NLogic::Equip * pEquip = pUser->GetEquip();
	if (NULL == pEquip)
	{
		DEBUGLOG("CS_REQ_FAIRY_REBIRTH : pEquip is NULL!!");
		SendFailFairyRebirth(pUser, ACK_UNKNOWN_ERROR);
		return;
	}

	// 장착된 페어리
	NLogic::Item * pEquipFairy = pEquip->GetItem(ITEM_EQUIP_POS_FAIRY);

	std::vector<NLogic::Item *> clsItemVector;

	for (int i = 0; i < fairyCount; i++)
	{
		uint64_t fairySeq;
		*pPacket >> fairySeq;

		NLogic::Item * pItem = pBag->PopItem(fairySeq);

		if (pItem == NULL)
		{
			std::for_each(clsItemVector.begin(), clsItemVector.end(), [&](NLogic::Item * pItem) {
				pBag->AddItem(pItem);
			} );

			DEBUGLOG("CS_REQ_FAIRY_REBIRTH : Invalid Fairy Seq! seq=%lld", fairySeq);
			SendFailFairyRebirth(pUser, ACK_UNKNOWN_ERROR);
			return;
		}

		clsItemVector.push_back(pItem);

		if (NULL != pEquipFairy && pEquipFairy->GetItemSeq() == fairySeq)
		{
			std::for_each(clsItemVector.begin(), clsItemVector.end(), [&](NLogic::Item * pItem) {
				pBag->AddItem(pItem);
			} );

			DEBUGLOG("CS_REQ_FAIRY_REBIRTH : Oops!! Equip Fairy");
			SendFailFairyRebirth(pUser, ACK_UNKNOWN_ERROR);
			return;
		}
	}

	NLogic::Item::Data clsData;
	if (false == NResource::Static::InstancePtr()->GetFairyGachya()->FairyRebirth(pUser, clsData, clsItemVector))
	{
		SendFailFairyRebirth(pUser, ACK_UNKNOWN_ERROR);

		// 에러가 발생하는 경우 재료 페어리 다시 인벤토리에 추가
		std::for_each(clsItemVector.begin(), clsItemVector.end(), [&](NLogic::Item * pItem) {
			pBag->AddItem(pItem);
		} );

		return;
	}

	bool bBagFull = false;
	NLogic::Item * pItem = pBag->AddItemWithData(clsData, bBagFull);
	if (NULL == pItem)
	{
		SendFailFairyRebirth(pUser, ACK_UNKNOWN_ERROR);

		// 에러가 발생하는 경우 재료 페어리 다시 인벤토리에 추가
		std::for_each(clsItemVector.begin(), clsItemVector.end(), [&](NLogic::Item * pItem) {
			pBag->AddItem(pItem);
		} );

		return;
	}

	// 재료 페어리 삭제 처리
	std::for_each(clsItemVector.begin(), clsItemVector.end(), [&](NLogic::Item * pItem) {
		pItem->DeleteDatabaseItemInfo(NLogic::Item::ItemStatus::EM_ITEM_STATUS_FAIRY_REBIRTH);
	} );

	// 패킷 전송
	::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();
	*pAck << static_cast<int16_t>(ACK_OK);
	*pAck << pItem->GetItemSeq();
	pAck->MakePacket(CMD_SC_REQ_FAIRY_REBIRTH);
	pUser->Send(pAck);
}

} /*NCommand*/ } /*ProjectZ*/
